def parse_hex_record(line):
    """
    解析HEX文件的一行记录。
    返回一个字典，包含记录的长度、地址、类型、数据和校验和。
    """
    if not line.startswith(":"):
        raise ValueError("Invalid HEX record: record must start with ':'")

    # 解析记录字段
    record_length = int(line[1:3], 16)
    address = int(line[3:7], 16)
    record_type = int(line[7:9], 16)
    data = line[9:9 + 2 * record_length]
    checksum = int(line[9 + 2 * record_length:9 + 2 * record_length + 2], 16)

    return {
        "length": record_length,
        "address": address,
        "type": record_type,
        "data": data,
        "checksum": checksum,
    }


def merge_hex_files(file_paths, output_path):
    """
    合并多个HEX文件。
    :param file_paths: 要合并的HEX文件路径列表
    :param output_path: 合并后的输出文件路径
    """
    merged_records = []
    current_base_address = 0  # 当前基地址（用于处理扩展地址记录）

    for file_path in file_paths:
        with open(file_path, "r") as file:
            for line in file:
                line = line.strip()
                if not line:
                    continue

                record = parse_hex_record(line)

                # 处理扩展地址记录
                if record["type"] == 0x04:  # 扩展线性地址记录
                    current_base_address = int(record["data"], 16) << 16
                    continue
                elif record["type"] == 0x02:  # 扩展段地址记录
                    current_base_address = int(record["data"], 16) << 4
                    continue

                # 跳过文件结束记录（除了最后一个文件）
                if record["type"] == 0x01:  # 文件结束记录
                    if file_path != file_paths[-1]:
                        continue

                # 计算绝对地址
                absolute_address = current_base_address + record["address"]

                # 检查地址冲突
                for existing_record in merged_records:
                    if (
                        existing_record["address"] <= absolute_address < existing_record["address"] + existing_record["length"]
                        or absolute_address <= existing_record["address"] < absolute_address + record["length"]
                    ):
                        raise ValueError(f"Address conflict detected at address {hex(absolute_address)}")

                # 添加记录到合并列表
                merged_records.append({
                    "address": absolute_address,
                    "length": record["length"],
                    "data": record["data"],
                    "type": record["type"],
                })

    # 按地址排序记录
    merged_records.sort(key=lambda x: x["address"])

    # 写入合并后的HEX文件
    with open(output_path, "w") as output_file:
        for record in merged_records:
            # 计算校验和
            data_bytes = bytes.fromhex(record["data"])
            checksum = sum(data_bytes) & 0xFF
            checksum = (~checksum + 1) & 0xFF  # 取补码

            # 写入记录
            output_file.write(
                f":{record['length']:02X}{record['address']:04X}{record['type']:02X}{record['data']}{checksum:02X}\n"
            )

        # 写入文件结束记录
        output_file.write(":00000001FF\n")

    print(f"HEX files merged into {output_path}")


# 示例用法
if __name__ == "__main__":
    hex_files = ["file1.hex", "file2.hex"]  # 要合并的HEX文件路径
    output_file = "merged.hex"  # 合并后的输出文件路径
    merge_hex_files(hex_files, output_file)
